import pandas as pd
from Strategy.views.service import my_page
from django.http import JsonResponse
from Django_Admin.settings import trade_col, backtest_col, summary_col, return_col, position_col, sim_backtest_col, \
    sim_position_col, sim_return_col, sim_strategy_col, sim_summary_col, sim_trade_col, market_data
# Create your views here.

from trade.models import TBackRun, TBackTrade, TBackReturn, TBackSummary, \
    TBackposition

# 策略管理
from django.views import View
from Strategy.models import t_direction_choices, t_offsetflag_choices
from Django_Admin.Common import Freq, Direction
from Django_Admin.enumType import MarketCodeDesc, DirectionDesc, OffsetFlagDesc
from datetime import datetime


# k线图
class detail_candlestik(View):
    def __init__(self):
        self.data = None

    # 回测详情中买卖点图例中数据的获取
    def get(self, request):
        ids = request.GET.get("backtestId")
        stg_id = ids.split('__')[0]
        batch_id = int(ids.split('__')[1])
        t_run = TBackRun
        t_trade = TBackTrade
        run_dict = t_run.objects.filter(StgID=stg_id, BatchID=batch_id).values().first()
        symbols = list(
            t_trade.objects.filter(StgID=stg_id, BatchID=batch_id).values(
                "Symbol").distinct())  # [{"Symbol": "fdsafsdaf"}]

        sym = request.GET.get('symbol')
        # 获取运行起止日期时间
        run_start_time = run_dict['Region'].split(',')[0]
        run_end_time = run_dict['Region'].split(',')[1]
        # 获取Freq
        run_freq = run_dict['Frequency']
        if run_freq == Freq.TICK.value:
            pass
        elif run_freq == Freq.MIN.value:
            # symbols, frequency, start_time, end_time=datetime.datetime.now(), fields=None
            fields = ['Timestamp', 'OpenPx', 'ClosePx', 'LowPx', 'HighPx']
            choice_symbol = [symbols[0].get("Symbol")] if sym == "" and symbols else [sym]
            temp_df = market_data.history(choice_symbol, run_freq, run_start_time, run_end_time, fields)
            temp_df['Timestamp'] = temp_df['Timestamp'].apply(lambda x: str(x))
            # 查询出来顺序是Timestamp  OpenPx  HighPx   LowPx  ClosePx， 需要转换列顺序
            market_data_df = pd.DataFrame()
            market_data_df.insert(0, 'Timestamp', temp_df['Timestamp'])
            market_data_df.insert(1, 'OpenPx', temp_df['OpenPx'])
            market_data_df.insert(2, 'ClosePx', temp_df['ClosePx'])
            market_data_df.insert(3, 'LowPx', temp_df['LowPx'])
            market_data_df.insert(4, 'HighPx', temp_df['HighPx'])
            # 获取买卖成交价格(只需要成交日期和成交价格)
            mysql_data = t_trade.objects.filter(
                StgID=stg_id, BatchID=batch_id, Symbol=choice_symbol[0]
            ).values('TradeTime', "TradePx", "Direction").order_by("TradeTime")
            # mongo_data = t_trade.find(
            #     {'StgID': stg_id, 'BatchID': batch_id, 'Symbol': choice_symbol[0]},
            #     {'TradeTime': 1, 'TradePx': 1, 'Direction': 1, '_id': 0}).sort([('TradeTime', 1)])
            trade_list = list(mysql_data)
            trade_df = pd.DataFrame(trade_list)
            trade_df['TradeTime'] = trade_df['TradeTime'].apply(lambda x: str(x))
            # 取买入列表
            bid_df = trade_df[trade_df.Direction == Direction.BID.value]
            bid_df.pop('Direction')
            tmp_df = bid_df.pop('TradeTime')
            bid_df.insert(0, 'TradeTime', tmp_df)
            bid_list = bid_df.values.tolist()
            # 取卖出列表
            ask_df = trade_df[trade_df.Direction == Direction.ASK.value]
            ask_df.pop('Direction')
            tmp_df = ask_df.pop('TradeTime')
            ask_df.insert(0, 'TradeTime', tmp_df)
            ask_list = ask_df.values.tolist()
            # 渲染
            self.data = {
                'data': market_data_df.values.tolist(),
                'is_KLine': True,
                'symbols': symbols,
                'Buy_TradePrice': bid_list,
                'Sell_TradePrice': ask_list,
            }

        elif run_freq == Freq.DAY.value:
            pass
        return JsonResponse(self.data, safe=False)


# symbol_button
def symbol_button(request):
    gid = request.GET.get('gid')
    sid = gid.split('__')[0]
    bid = int(gid.split('__')[1])
    t_trade = TBackTrade
    symbols = []
    sym = t_trade.objects.filter(StgID=int(sid), BatchID=int(bid)).values("Symbol").first()
    if sym:
        sym = sym.get("Symbol")
    symbols.append(sym)
    # print(sym)
    return JsonResponse(symbols, safe=False)


# 成交信息-table
def get_filed_display(filed, key):
    if filed == 'Direction':
        for i in t_direction_choices:
            if i[0] == str(key):
                return i[1]
    elif filed == 'Offset':
        for i in t_offsetflag_choices:
            if i[0] == str(key):
                return i[1]


class detail_trade_list_table(View):

    def __init__(self):
        self.data = None

    # 回测详情中成交信息的数据获取
    def get(self, request):
        t_trade = TBackTrade
        ids = request.GET.get("sid")
        lim = request.GET.get('limit', None)
        off = request.GET.get('offset', None)
        search = request.GET.get('search', '')
        stg_id = ids.split('__')[0]
        batch_id = int(ids.split('__')[1])

        mysql_data = t_trade.objects.filter(
            StgID=stg_id, BatchID=batch_id, Symbol__startswith=search
        ).values("TradeTime", "TradePx", "Direction", "Offset", "Qty", "AccountID", "Symbol", "ExchID", "TradeYTM")

        # mongo_data = t_trade.find(
        #     {'StgID': stg_id, 'BatchID': batch_id, 'Symbol': {'$regex': search}},
        #     {'TradeTime': 1, 'TradePx': 1, 'Direction': 1, 'Offset': 1, 'Qty': 1,
        #      'AccID': 1, 'Symbol': 1, 'ExchID': 1, '_id': 0})
        trade_list = list(mysql_data)
        for i in trade_list:
            i["AccID"] = i['AccountID']
            i["Symbol"] = i['Symbol']
            i["ExchID"] = MarketCodeDesc.get(str(i['ExchID']), '未知')
            i["TradeTime"] = str(i['TradeTime'])
            i["TradePx"] = i['TradePx']
            i["Qty"] = str(i['Qty'])
            i["Direction"] = DirectionDesc.get(i['Direction'], '未知')
            i["Offset"] = OffsetFlagDesc.get(i['Offset'], '未知')
            i['TradeYTM'] = i['TradeYTM']
        result = my_page(trade_list, lim, off)
        return JsonResponse(result, safe=False)


class detail_cumulativereturns(View):

    def __init__(self):
        self.data = None

    # 回测详情中ECharts净值曲线的数据获取
    def get(self, request):
        id = request.GET.get("backtestId")
        btc = TBackRun
        rc = TBackReturn
        # sim_run表中的_id在return表中找不到
        StgID = id.split('__')[0]
        BatchID = int(id.split('__')[1])
        backObj = btc.objects.filter(StgID=StgID, BatchID=BatchID).values().first()
        if backObj is None:
            self.data = {
                'retDate': [],
                'retData': []
            }
            return JsonResponse(self.data, safe=False)
        if rc.objects.filter(StgID=backObj['StgID'], BatchID=backObj["BatchID"]).values().count() != 0:
            # if rc.find({'strategy_id': backObj['StgID'], 'BacktestID': backObj['BatchID']}).count() != 0:
            returnObj = rc.objects.filter(StgID=backObj["StgID"], BatchID=backObj["BatchID"]).values().first()
            # returnObj = rc.find_one({'strategy_id': backObj['StgID'], 'BacktestID': backObj['BatchID']})
            retDate = str(returnObj['date']).strip("[").rstrip("]").rstrip(',').split(',')
            retData = returnObj['data'].strip('[').rstrip(']').rstrip(',').split(',')
            retDateList = []
            retDataList = []
            for item in retDate:
                retDateList.append(item.replace("\'", ''))
            for item in retData:
                retDataList.append(round(float(item.replace("\'", '')), 5))
            self.data = {
                'retDate': retDateList,
                'retData': retDataList
            }
        return JsonResponse(self.data, safe=False)


# 收益率统计-图1
class detail_monthlyreturns(View):
    def __init__(self):
        self.data = None

    def get(self, request):
        return JsonResponse(self.data, safe=False)


# 收益率统计-图2
class detail_annualreturns(View):
    def __init__(self):
        self.data = None

    def get(self, request):
        return JsonResponse(self.data, safe=False)


# 收益率统计-图3
class detail_monthDistribution(View):
    def __init__(self):
        self.data = None

    def get(self, request):
        return JsonResponse(self.data, safe=False)


# 收益率统计-大图
class detail_returnsBoxPlot(View):
    def __init__(self):
        self.data = None

    def get(self, request):
        return JsonResponse(self.data, safe=False)


# 收益统计
class detail_incomeStatistics(View):
    def __init__(self):
        self.data = None

    # 回测详情中的收益统计的数据获取
    def get(self, request):
        btc = TBackRun
        sr = TBackSummary
        id = request.GET.get("backtestId")
        StgID = id.split('__')[0]
        BatchID = int(id.split('__')[1])
        backObj = btc.objects.filter(StgID=StgID, BatchID=BatchID).values().first()
        # backObj = btc.find_one({'StgID': StgID, 'BatchID': BatchID})
        if sr.objects.filter(StgID=backObj['StgID'], BatchID=backObj["BatchID"]).count() != 0:
            # if sr.find({'StrategyID': backObj['StgID'], 'BacktestID': backObj['BatchID']}).count() != 0:
            item = sr.objects.filter(StgID=backObj["StgID"], BatchID=backObj["BatchID"]).values().first()
            # item = sr.find_one({'StrategyID': backObj['StgID'], 'BacktestID': backObj['BatchID']})
            obj = {
                "annual_return": round(float(item['AnnualRet']) * 100, 3),
                "total_return": round(float(item['PL']) * 100, 3),
                "max_draw_down": round(float(item['MaxDrawndown']) * 100, 3),
                "annual_volatility": round(float(item['AnnualVolatility']), 4),
                "sharpe_ratio": round(float(item['SharpRatio']), 4),
                "calmar_ratio": round(float(item['CalmarRatio']), 4),
                "stability_of_time_series": round(float(item['StabilityOfTimeseries']), 4),
                "omega_ratio": round(float(item['OmegaRatio']), 4),
                "sortino_ratio": round(float(item['SortinoRatio']), 4),
                "start_date": item['SimStartDate'],
                "end_date": item['SimEndDate'],
            }
            self.data = obj
        return JsonResponse(self.data, safe=False)


def position(request):
    sd = request.GET["sid"]
    sid = sd.split('__')[0]
    bid = sd.split('__')[1]
    lim = request.GET.get('limit', None)
    off = request.GET.get('offset', None)
    search = request.GET.get('search', '')
    pr = TBackposition

    position_list = list(pr.objects.filter(stgid=sid, batchid=int(bid), symbol__contains=search).values())
    # userList = list(pr.find({"StgID": sid, "BatchID": int(bid), "Symbol": {'$regex': search}}))
    for i in position_list:
        i["accountID"] = i['accountid']
        i["symbol"] = i['symbol']
        i["exch"] = MarketCodeDesc.get(str(i['exchid']), '')
        i["date"] = i['tradingday']
        i["close"] = i['closepx']
        i["bidQty"] = i['buyqty']
        i["bidPx"] = round(i['buyopenpx'], 2)
        i["bidMargin"] = round(i['buymargin'], 2)
        i["bidPNL"] = round(i['buypnl'], 2)
        i["askQty"] = i['sellqty']
        i["askPx"] = round(i['sellopenpx'], 2)
        i["askMargin"] = round(i['sellmargin'], 2)
        i["askPNL"] = round(i['sellpnl'], 2)
    result = my_page(position_list, lim, off)
    return JsonResponse(result, safe=False)
